/*
 * JNIObject.h  0.4.0 / Nov 14, 2010
 *
 * Copyright (c) 2010 - 2011, cute4j.com and contributors.
 *
 * This software is licensed under the terms of the LGPL license version 2.1.
 * A copy of this license is included in the file LICENSE-LGPL.txt.
 */
#ifndef JNIOBJECT_H
#define JNIOBJECT_H

#include "Cute4jCommon.h"

// JNIObject Class. ------------------------------------------------------------

/*!
 * \brief JNI Object Wrapper.
 *
 * \author Slobodan Vrkacevic
 * \version 0.4.0
 */
class CUTE4J_EXPORT JNIObject
{
public:
  JNIObject(JNIEnv *env, jobject obj);
  virtual ~JNIObject();
private:
  JNIObject(const JNIObject &);
public:
  inline JNIEnv *env() const;
  inline jweak ref() const;
  inline bool isSameThread(JNIEnv *env) const;
public:
  bool isLive();
  void checkException();
  bool testException();
  void fatalError(const char *errorMessage);
  void throwInternalError(const char *errorMessage = 0);
  void throwOutOfMemoryError(const char *errorMessage = 0);
  void throwRuntimeExcpetion(const char *exceptionMessage = 0);
  jfieldID getFieldID(const char *name, const char *sig);
  jmethodID getMethodID(const char *name, const char *sig);
  jobject getObjectField(jfieldID fieldID);
  void setObjectField(jfieldID fieldID, jobject val);
  jboolean getBooleanField(jfieldID fieldID);
  void setBooleanField(jfieldID fieldID, jboolean val);
  jbyte getByteField(jfieldID fieldID);
  void setByteField(jfieldID fieldID, jbyte val);
  jchar getCharField(jfieldID fieldID);
  void setCharField(jfieldID fieldID, jchar val);
  jshort getShortField(jfieldID fieldID);
  void setShortField(jfieldID fieldID, jshort val);
  jint getIntField(jfieldID fieldID);
  void setIntField(jfieldID fieldID, jint val);
  jlong getLongField(jfieldID fieldID);
  void setLongField(jfieldID fieldID, jlong val);
  jfloat getFloatField(jfieldID fieldID);
  void setFloatField(jfieldID fieldID, jfloat val);
  jdouble getDoubleField(jfieldID fieldID);
  void setDoubleField(jfieldID fieldID, jdouble val);
  jclass getObjectClass();
  bool callObjectMethod(jobject &result, jmethodID methodID, ...);
  bool callBooleanMethod(jboolean &result, jmethodID methodID, ...);
  bool callByteMethod(jbyte &result, jmethodID methodID, ...);
  bool callCharMethod(jchar &result, jmethodID methodID, ...);
  bool callShortMethod(jshort &result, jmethodID methodID, ...);
  bool callIntMethod(jint &result, jmethodID methodID, ...);
  bool callLongMethod(jlong &result, jmethodID methodID, ...);
  bool callFloatMethod(jfloat &result, jmethodID methodID, ...);
  bool callDoubleMethod(jdouble &result, jmethodID methodID, ...);
  bool callVoidMethod(jmethodID methodID, ...);
  jstring toJString();
  jstring newJString(const jchar *uchars, jsize len);
  jstring newJStringUTF(const char *bytes);
private:
  JNIEnv *m_env;
  jweak m_ref;
};

// JNIObject :: Protected Inline Member Functions. -----------------------------

/*!
 * \brief Returns JNIEnv pointer.
 *
 * \return env JNIEnv pointer
 */
inline JNIEnv *JNIObject::env() const
{
  return m_env;
}

/*!
 * \brief Returns weak reference to the Java object.
 *
 * \return weak reference to the Java object
 */
inline jweak JNIObject::ref() const
{
  return m_ref;
}

/*!
 * \brief Returns \c true if the specified JNIEnv pointer is same as \a m_env.
 *
 * \return \c true if JNIEnv pointer \a env is same as \a m_env
 */
inline bool JNIObject::isSameThread(JNIEnv *env) const
{
  return (m_env == env);
}

#endif // JNIOBJECT_H
